Terraform を Google Cloud マネージド環境で実行する! Infrastructure Manager とは? #cm_google_cloud_adcal_2024
はじめに
クラスメソッドの Google Cloud Advent Calendar 2024 の 3 日目のブログです!
Google Cloud Advent Calendar 2024 では Google Cloud が大好きな弊社エンジニアが技術ブログを持ち回りで毎日執筆中ですので、ご覧になっていただけると嬉しいです。
本日は Infrastructure Manager について解説いたします。
Infrastructure Manager とは
2023/8 に GA となった Infrastructure Manager (以降 Infra Manager。Google Cloud 公式ドキュメントと同一の表現。) は Terraform を Google Cloud マネージド環境で実行できるサービスです。
Google Cloud のインフラを管理する Terraform の実行環境として、 Google Cloud 上の Cloud Shell や Workstations、HCP Terraform、ローカル開発環境、など様々な選択肢があると思います。Infra Manager はこのような Terraform を実行するための環境をユーザ自身で用意せずとも、Infrastructure Manager API へのリクエストによって Google Cloud マネージド環境上でサーバレスに Terraform を実行できます。
以下は ローカル開発環境から Terraform によってリソース作成を実行する場合の概要図です。
Terraform によるリソース作成の概要
Infra Manager でリソース作成する場合、API リクエストで Terraform によるリソース作成を Infra Manager に指示するイメージになります。
概要図は以下です。詳細アーキテクチャは後述します。
Infra Manager によるリソース作成の概要
チーム開発においては、Terraform 実行環境の統一化、Terraform 実行におけるデプロイのリビジョン管理やログの一元管理、state ファイルの保管など様々な課題がありますが、Infrastructure Manager API へのアクセスが可能な環境であれば事前の整備無しで利用が開始できます。
詳細は以下をご参照ください。
アーキテクチャ概要
Infra Manager の実体は、
- API リクエストを受け付ける Infrastructure Manager API
- Infra Manager からのリクエストを受けて Terraform を実行するための Cloud Build ジョブ
- Terraform 実行に関わるログや state ファイルなどを保存するための Cloud Storage
の組み合わせです。
Infra Manager からのリクエストを受けて、裏側で実行される Cloud Build ジョブの詳細は以下です。
- Terraform がプリインストールされた Terraform 実行環境用のコンテナベースイメージを Google Cloud 管理の Artifact Registry リポジトリからダウンロードし起動
- Terraform 設定ファイルのダウンロード
terraform init
によるプロバイダのインストールなどの Terraform 初期化terraform validate
による Terraform 設定ファイルのチェックterraform apply
またはterraform destroy
Infra Manager によって生成されたログやメタデータは Cloud Storage のバケットに保存されます。保存対象のバケットはユーザ指定が可能です。
terraform apply
によって生成された state ファイルは Google Cloud 管理の Cloud Storage バケットに保存されます。こちらはユーザ指定ができません。
Infra Manager の詳細アーキテクチャ
どのようなユースケースで利用できる?
実際に触ってみた感想から以下のようなユースケースで利用できるのではと推測しています。
- OSS 利用のセキュリティ制限などにより、ローカル開発環境への Terraform 自体のインストールやプロバイダのインストールに高いハードルがある
- state ファイルの保管戦略を検討することなく、マネージド領域で一元管理できる
- Terraform 実行に関するログやリビジョンの一元管理ができる
正直なところ、現在の機能では多くのユースケースで利用できるイメージは湧いていませんが、非常に厳しいセキュリティ制限のなかで Terraform を利用する場合の選択肢になるのではとは考えています。
触ってみた
実際に Infra Manager を利用して Terraform によるリソース作成をしてみました。
これから実行する手順には Cloud Infrastructure Manager (roles/config.admin
) の IAM ロールが必要ですが、今回はオーナー権限で手順を実行しています。
1. Infrastructure Manager API の有効化
Cloud Shell から以下を実行し、Infrastructure Manager API を有効化します。
gcloud services enable config.googleapis.com
2. サービスアカウントの作成と IAM ロールの付与
Infra Manager に付与するサービスアカウントを作成します。ここではサービスアカウント名を infra-mng
としました。
gcloud iam service-accounts create infra-mng
作成したサービスアカウントに、Cloud Infrastructure Manager Agent (roles/config.agent
) を付与します。Infra Manager をユーザー指定のサービスアカウントで動作させるために必要な権限となります。
export PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member="serviceAccount:infra-mng@${PROJECT_ID}.iam.gserviceaccount.com" --role=roles/config.agent
※コマンド実行後、condition の設定について聞かれたら [2] None
を選択してください。
また、このサービスアカウントには Terraform でデプロイするインフラを作成するために必要な権限も付与する必要があります。本検証では、VPC(default) に Compute Engine VM インスタンスを作成する簡易的なコードを用意します。そのため、VM インスタンスの作成に必要なCompute インスタンス管理者(v1) (roles/compute.instanceAdmin.v1
) のIAM ロールのみを付与します。
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member="serviceAccount:infra-mng@${PROJECT_ID}.iam.gserviceaccount.com" --role=roles/compute.instanceAdmin.v1
※コマンド実行後、condition の設定について聞かれたら [2] None
を選択してください。
3. Terraform 設定ファイルの準備
本検証では、default の VPC に Compute Engine VM インスタンスを作成するだけの簡易的なコードとします。
以下の Terraform 設定ファイルを Cloud Shell 上に用意しておきます。
provider "google" {
project = var.project_id
}
resource "google_compute_instance" "default" {
name = "tf-instance"
machine_type = "e2-micro"
zone = "asia-northeast1-a"
boot_disk {
initialize_params {
image = "projects/debian-cloud/global/images/debian-12-bookworm-v20241112"
size = 20
type = "pd-balanced"
}
}
network_interface {
network = "default"
}
}
variable "project_id" {
type = string
}
4. Terraform 設定ファイルの配置とログ等保存先バケットの作成
今回は Cloud Storage バケットにこれらの Terraform 設定ファイルを配置し、Infra Manager 実行時に参照するようにしたいと思います。Cloud Shell にて Terraform 設定ファイル用のバケットを作成し、Terraform 設定ファイルをコピーします。
gsutil mb gs://infra-mgr-tf-${PROJECT_ID}/
gsutil cp provider.tf main.tf variables.tf gs://infra-mgr-tf-${PROJECT_ID}/
また、Terraform 実行に関するログやメタデータを保存するためのバケットも用意しておきます。
gsutil mb gs://infra-mgr-tf-artifacts-${PROJECT_ID}/
5. Infra Manager でデプロイをプレビュー
Cloud Shell より以下コマンドでプレビューを作成します。
gcloud infra-manager previews create projects/${PROJECT_ID}/locations/us-central1/previews/preview-01 \
--service-account projects/${PROJECT_ID}/serviceAccounts/infra-mng@${PROJECT_ID}.iam.gserviceaccount.com \
--gcs-source=gs://infra-mgr-tf-${PROJECT_ID} \
--artifacts-gcs-bucket=gs://infra-mgr-tf-artifacts-${PROJECT_ID} \
--input-values=project_id=${PROJECT_ID}
preview-01
は作成するプレビューの名前です。
--service-account
で先ほど作成したサービスアカウントをアタッチします。
--gcs-source
は Terraform 設定ファイルの配置先バケットを指定します。
--artifacts-gcs-bucket
はログ等保存先のバケットを指定します。
--input-values
は入力変数と値を指定します。
コマンドの詳細は以下をご参照ください。
プレビューを実行すると、--artifacts-gcs-bucket
で指定したバケットにログやプレビュー結果が配置されます。
preview-01
配下の preview_results/artifacts/planned-resources.json
を確認すると、作成予定のリソースの情報が確認できました。
$ gsutil cat gs://infra-mgr-tf-artifacts-${PROJECT_ID}/new-previews/preview-01/preview_results/artifacts/plann
ed-resources.json
[
{
"tfAddress": "google_compute_instance.default",
"tfType": "google_compute_instance",
"cai": {
"compute.googleapis.com/Instance": {
"id": "//compute.googleapis.com/projects/<project_id>/zones/asia-northeast1-a/instances/tf-instance"
}
},
"intent": "CREATE",
"state": "PLANNED"
}
6. Infra Manager でデプロイする
Cloud Shell より以下コマンドでデプロイを実行してみます。
gcloud infra-manager deployments apply projects/${PROJECT_ID}/locations/us-central1/deployments/deployment-01 \
--service-account projects/${PROJECT_ID}/serviceAccounts/infra-mng@${PROJECT_ID}.iam.gserviceaccount.com \
--gcs-source gs://infra-mgr-tf-${PROJECT_ID} \
--artifacts-gcs-bucket=gs://infra-mgr-tf-artifacts-${PROJECT_ID} \
--input-values=project_id=${PROJECT_ID}
deployment-01
は作成するデプロイメントのIDです。
その他指定コマンドはプレビューと同様です。
コマンドの詳細は以下をご参照ください。
デプロイが成功すると Compute Engine が作成されていることが確認できると思います。
以下コマンドでデプロイの状態を確認してみます。以下のような表示が確認できます。
$ gcloud infra-manager deployments describe projects/${PROJECT_ID}/locations/us-central1/deployments/deployment-01
artifactsGcsBucket: gs://infra-mgr-tf-artifacts-<PROJECT_ID>
createTime: '2024-12-02T12:31:58.417695223Z'
latestRevision: projects/<PROJECT_ID>/locations/us-central1/deployments/deployment-01/revisions/r-0
lockState: UNLOCKED
name: projects/<PROJECT_ID>/locations/us-central1/deployments/deployment-01
serviceAccount: projects/<PROJECT_ID>/serviceAccounts/infra-mng@<PROJECT_ID>.iam.gserviceaccount.com
state: ACTIVE
stateDetail: revision "projects/<PROJECT_ID>/locations/us-central1/deployments/deployment-01/revisions/r-0"
applied
terraformBlueprint:
gcsSource: gs://infra-mgr-tf-<PROJECT_ID>
inputValues:
project_id:
inputValue: <PROJECT_ID>
tfVersion: 1.5.7
updateTime: '2024-12-02T12:45:11.762359731Z'
latestRevision:
に revisions/r-0
と記載がありますが、これがリビジョン番号となります。同一のデプロイメントで更新をかけると、リビジョンが r-1
, r-2
... と増えていきます。
7. デプロイしたリソースを Infra Manager で削除する
デプロイしたリソースを Infra Manager で削除するには、以下コマンドで作成したデプロイメント ID を指定します。
gcloud infra-manager deployments delete projects/${PROJECT_ID}/locations/us-central1/deployments/deployment-01
You are about to delete deployment [deployment-01]
Do you want to continue (Y/n)? Y
実行が成功すると、デプロイした Compute Engine が削除されることが確認できると思います。
state ファイルの管理
冒頭で説明したように、デプロイされた state ファイルは Infra Manager によってマネージドの範囲で Google Cloud 管理の Cloud Storage バケットに保存されるため、Infra Manager API 経由での取得が必要となります。
state ファイルの取得を試すため、もう一度以下コマンドでデプロイします。今度はデプロイメント ID を deployment-02
にしてみます。
gcloud infra-manager deployments apply projects/${PROJECT_ID}/locations/us-central1/deployments/deployment-02 \
--service-account projects/${PROJECT_ID}/serviceAccounts/infra-mng@${PROJECT_ID}.iam.gserviceaccount.com \
--gcs-source gs://infra-mgr-tf-${PROJECT_ID} \
--artifacts-gcs-bucket=gs://infra-mgr-tf-artifacts-${PROJECT_ID} \
--input-values=project_id=${PROJECT_ID}
gcloud infra-manager deployments export-statefile
コマンドで state ファイル保存先の URL を取得し、curl で terraform.tfstate
をダウンロードします。
SIGNED_STATE_DOWNLOAD_URL=$(gcloud infra-manager deployments export-statefile deployment-02 --project ${PROJECT_ID} --location us-central1 --format="get(signedUri)")
curl -s -X GET --output terraform.tfstate ${SIGNED_STATE_DOWNLOAD_URL}
上記で取得した state ファイルは編集して API 経由でアップロードすることも可能です。詳細は以下をご参照ください。
料金
ここまででご説明したように Infra Manager の実体は Cloud Build ジョブと Cloud Storage バケットであり、これらに対しての課金のみが発生します。
Infrastructure Manager API へのリクエストについては課金されません。
詳細は以下をご参照ください。
制限事項や気になる点
-
asia-northeast1(東京リージョン)でサポートされていない。
対応ロケーションに記載の通り、東京リージョンで利用できないとされています。しかし、デプロイ時に asia-northeast1 を指定するとなぜかデプロイが成功しました。(Cloud Build ジョブも state ファイル保存先も asia-northeast1 での実行となった)
明示的にサポート対象として明記されていないため、asia-northeast1 での利用は控えた方が良いでしょう。 -
サポートバージョンが以下のみで、比較的新しいバージョンが利用できない。
1.2.3 / 1.3.10 / 1.4.7 / 1.5.7 -
追加 / 削除 / 変更されるリソースについて、
terraform plan
のようにわかりやすく表示する機能が無い。(プレビュー機能はあるが、terraform plan
のようにわかりやすく表示されるわけではない) -
terraform apply
では、追加 / 削除 / 変更されるリソースについての事前確認ができるが、Infra Manager ではコマンド実行時の事前確認はできない。 -
プレビューを実施するたびに新しいプレビューを作成する必要があり、プレビューが乱立し管理が煩雑となる。
terraform plan
のように手軽に確認できない。
おわりに
Infrastructure Manager について解説してみました。セキュリティ制限のある環境やログ等の一元管理といった点で有用なサービスである一方、使い勝手の点では気になる点がいくつかありました。
比較的新しいサービスではあるため、近い将来の機能追加などにも期待したいと思います。
Google Cloud Advent Calendar 2024 の 明日 12/4 投稿は 根本夏瑠 です。